//
// Created by 张亦乐 on 2018/9/17.
//
#include "ArenaSrv.hpp"
#include <functional>

#include "Baller.hpp"
#include "ArenaRoom.hpp"

#include "proto/MsgTimer.pb.h"
#include "proto/MsgBattle.pb.h"
struct TcpConnectorDelete
{
    void operator()(TcpConnector* conn)const
    {
        Baller* tie = (Baller*)conn->GetTie();
        if(tie != nullptr)
        {
            printf("Baller id = %lu name = %s lost connect\n",tie->ID(),tie->Name().c_str());
            ArenaRoomMgr::GetInstance().BallerExitRoom(tie->ID());
            BallerMgr::GetInstance().RemoveBaller(tie->ID());
        }
		delete conn;
    }
};

using namespace std;
using namespace std::placeholders;
ArenaSrv::ArenaSrv(const char* name, Reactor& reactor):
                    _name(name),
                    _reactor(reactor),
                    _tcpServer(reactor,0,"*",9876,true)
{
    _tcpServer.SetInitedCallback(std::bind(&ArenaSrv::onInit,this));
    _tcpServer.SetMessageCallback(std::bind(&ArenaSrv::onMessageCallback,this,_1,_2));
    // _tcpServer.SetClosedCallback(std::bind(&ArenaSrv::onClosedCallback,this,_1));
    _tcpServer.SetCreateCallback(std::bind(&ArenaSrv::onCreate,this,_1,_2,_3));
}

ArenaSrv::~ArenaSrv()
{

}

void ArenaSrv::updateLogicFrame()
{//1秒钟10帧 = 100ms一帧
	ProtoMsg::FrameTimer frameMsg;
	_center.PushProtoMsg(frameMsg);
}

void ArenaSrv::onInit()
{
    //服务器逻辑帧间隔100ms
    int64_t mircs = 66 * 1000;
	_reactor.RunRepeated(std::bind(&ArenaSrv::updateLogicFrame,this),mircs);
}

TcpConnectorPtr ArenaSrv::onCreate(Reactor& reactor,int fd,char* name)
{
    return TcpConnectorPtr(new TcpConnectorFrom(reactor,fd,name),TcpConnectorDelete());
}

void ArenaSrv::onConnectedCallback(TcpConnectorPtr conn)
{

}

void ArenaSrv::onMessageCallback(TcpConnectorPtr tcpConn,Buffer& buffer)
{
    if(!_center.Parse(buffer,tcpConn))
    {
        tcpConn->ForceClose();
    }
}

void ArenaSrv::onClosedCallback(TcpConnectorPtr conn)
{

}

void ArenaSrv::Loop()
{
    _center.Start();
    _tcpServer.Start();
    _reactor.Loop();
}
